<?php
namespace HC\Swoole;

abstract class Timer
{
    public static $timers = [];

    abstract public function timer() : bool;
    abstract public function execute();

    final static public function start()
    {
        $count = count(static::$timers);

        foreach (static::$timers as $class => $pid) {
            if ($pid) {
                $count--;
                continue;
            }

            $process = new \swoole_process(function (\swoole_process $worker) use ($class) {
                $timer = new $class;

                if ($timer->timer()) {
                    try {
                        $timer->execute();
                    } catch (\Throwable $e) {}
                }

                unset($timer);
                $worker->exit(1);
            });

            static::$timers[$class] = $process->start();
        }

        while ($count--) {
            $rs  = \swoole_process::wait();
            $key = array_search($rs['pid'] ?? 0, static::$timers);
            if ($key && isset(static::$timers[$key])) {
                static::$timers[$key] = 0;
            }
        }
    }

    final static public function exists(string $class)
    {
        return isset(static::$timers[$class]) ? true : false;
    }

    final static public function register(string $class)
    {
        \HC\Swoole\sw_class_exists($class);

        if (!is_subclass_of($class, self::class)) {
            throw new \UnexpectedValueException('Require subclass of "' . self::class . '"');
        }

        static::$timers[$class] = 0;
    }
}